package it.tukano.swingdeco.event;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * A var event source
 * @author pgi
 * @param <V> the type of the variable for the var event sent by this source
 * @param <T> the type of the value for the var event sent by this source
 */
public class VarEventSource<V, T> {

    /** The delegate source of this event source*/
    private Object delegate;

    /** Listeners bound to this source */
    private final List<VarEventListener<V, T>> listeners = new CopyOnWriteArrayList<VarEventListener<V, T>>();

    /**
     * Instance initializer
     */
    public VarEventSource() {
    }

    /**
     * Set the source used to create the events
     * @param source the source of the events
     * @return this
     */
    public VarEventSource<V, T> setDelegateOf(Object source) {
        this.delegate = source;
        return this;
    }

    /**
     * Add a listener to this source
     * @param listener the listener to add
     */
    public void addVarEventListener(VarEventListener<V, T> listener) {
        listeners.add(listener);
    }

    /**
     * Remove a listener from this source
     * @param listener the listener to remove
     */
    public void removeVarEventListener(VarEventListener<V, T> listener) {
        listeners.remove(listener);
    }

    /**
     * Send a var event to the registered listeners
     * @param var the variable that has changed
     * @param value the new value of the variable
     */
    public void notifyEvent(V var, T value) {
        Object source = delegate == null ? this : delegate;
        VarEvent<V, T> event = new VarEvent<V, T>(source, var, value);
        for (VarEventListener<V, T> listener : listeners) {
            listener.varEventPerformed(event);
        }
    }
}
